package com.example.test;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
/**
* 一个检测手机摇晃的监听器
*/
public class ShakeListener implements SensorEventListener {
private static final int SPEED_SHRESHOLD = 3000;// 速度阈值，当摇晃速度达到这值后产生作用
private static final int UPTATE_INTERVAL_TIME = 70;// 两次检测的时间间隔
private SensorManager sensorManager;// 传感器管理器
private Sensor sensor;// 传感器
private OnShakeListener onShakeListener;// 重力感应监听器
private Context mContext;// 上下文
private float lastX;// 手机上一个位置时重力感应坐标
private float lastY;
private float lastZ;
private long lastUpdateTime;// 上次检测时间
public ShakeListener(Context c) {//构造器
  mContext = c; // 获得监听对象
  start();
}
public void start() {// 开始
  sensorManager = (SensorManager) mContext 
    .getSystemService(Context.SENSOR_SERVICE); // 获得传感器管理器
  if (sensorManager != null) {
   sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);// 获得重力传感器
  }
  if (sensor != null) {
   sensorManager.registerListener(this, sensor,
     SensorManager.SENSOR_DELAY_GAME);// 注册
  }
}
public void stop() {// 停止检测
  sensorManager.unregisterListener(this);
}
public void setOnShakeListener(OnShakeListener listener) {
  onShakeListener = listener;// 设置重力感应监听器
}
public void onSensorChanged(SensorEvent event) {// 重力感应器感应获得变化数据
  long currentUpdateTime = System.currentTimeMillis();  // 现在检测时间
  long timeInterval = currentUpdateTime - lastUpdateTime;  // 两次检测的时间间隔
  if (timeInterval < UPTATE_INTERVAL_TIME)  // 判断是否达到了检测时间间隔
   return;
  lastUpdateTime = currentUpdateTime;  // 现在的时间变成last时间
  float x = event.values[0];  // 获得x,y,z坐标
  float y = event.values[1];
  float z = event.values[2];
  float deltaX = x - lastX;  // 获得x,y,z的变化值
  float deltaY = y - lastY;
  float deltaZ = z - lastZ;
  lastX = x;  // 将现在的坐标变成last坐标
  lastY = y;
  lastZ = z;
  double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ
    * deltaZ)/ timeInterval * 10000;  //sqrt 返回最近的双近似的平方根
  if (speed >= SPEED_SHRESHOLD) {
   onShakeListener.onShake();  // 达到速度阀值，发出提示
  }
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public interface OnShakeListener {// 摇晃监听接口
  public void onShake();
}
}

